package com.aloda.service.impl;

import com.aloda.constant.*;
import com.aloda.context.BaseContext;
import com.aloda.dto.*;
import com.aloda.entity.User;
import com.aloda.exception.AccountLockedException;
import com.aloda.exception.AccountNotFoundException;
import com.aloda.exception.IdError;
import com.aloda.exception.PasswordErrorException;
import com.aloda.mapper.UserMapper;
import com.aloda.properties.JwtProperties;
import com.aloda.result.PageResult;
import com.aloda.service.UserService;
import com.aloda.utils.JwtUtil;
import com.aloda.utils.NicknameUtil;
import com.aloda.vo.UserEditVO;
import com.aloda.vo.UserInfoVO;
import com.aloda.vo.UserLoginVO;
import com.aloda.vo.UserPageVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 分页查询用户
     *
     * @param userPageDTO
     * @return
     */
    @Override
    public PageResult pageQuery(UserPageDTO userPageDTO) {
        //转换到北京时区
        if(userPageDTO.getBegin()!=null&&userPageDTO.getEnd()!=null){
            userPageDTO.setBegin(userPageDTO.getBegin().plusHours(8));
            userPageDTO.setEnd(userPageDTO.getEnd().plusHours(8));
        }
        //分页查询
        PageHelper.startPage(userPageDTO.getPage(), userPageDTO.getPageSize());
        Page<UserPageVO> page = userMapper.pageQuery(userPageDTO);
        PageResult pageResult = new PageResult(page.getTotal(),page.getResult());
        return pageResult;
    }

    /**
     * 后台新增用户
     *
     * @param userAddDTO
     */
    @Override
    public void addUser(UserAddDTO userAddDTO) {
        //创建用户对象
        User user = new User();
        BeanUtils.copyProperties(userAddDTO,user);
        //如果昵称为空获取随机昵称
        if(userAddDTO.getNickname() == null || userAddDTO.getNickname().isEmpty()||userAddDTO.getNickname().length()==0){
            user.setNickname(NicknameUtil.generateNickname());
        }
        //设置默认密码
        String pwd = DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes());
        user.setPassword(pwd);
        //设置公共字段
        user.setAuthority(AuthorityConstant.NORMAL_USER);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.addUser(user);
    }

    /**
     * 编辑用户信息回显
     *
     * @param id
     * @return
     */
    @Override
    public UserEditVO getUserById(Long id) {
        User user = userMapper.getUserById(id);
        UserEditVO userEditVO = new UserEditVO();
        BeanUtils.copyProperties(user,userEditVO);
        return userEditVO;
    }

    /**
     * 更新用户信息
     *
     * @param userEditDTO
     */
    @Override
    public void updateUser(UserEditDTO userEditDTO) {
        User user = new User();
        BeanUtils.copyProperties(userEditDTO,user);
        if(user.getNickname().length()==0|| Objects.equals(user.getNickname(),"")){
            user.setNickname(NicknameUtil.generateNickname());
        }
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
    }

    /**
     * 用户权限设置
     *
     * @param id
     * @param auth
     */
    @Override
    public void setAuth(Long id, Integer auth) {
        User user = userMapper.getUserById(id);
        user.setAuthority(auth);
        userMapper.update(user);
    }

    /**
     * 批量注销用户
     *
     * @param ids
     */
    @Override
    public void logoutUser(List<Long> ids) {
        userMapper.logoutUser(ids);
    }

    /**
     * 用户端用户注册
     *
     * @param userRegisterDTO
     */
    @Override
    public void register(UserRegisterDTO userRegisterDTO) {
        User user = new User();
        userRegisterDTO.setPassword(DigestUtils.md5DigestAsHex(userRegisterDTO.getPassword().getBytes()));
        BeanUtils.copyProperties(userRegisterDTO,user);
        user.setName(UserConstant.NULL_CONTENT);
        user.setPhone(UserConstant.NULL_CONTENT);
        user.setMail(UserConstant.NULL_CONTENT);
        user.setAvatarUrl(null);
        user.setGender(UserConstant.DEFAULT_GENDER);
        user.setAuthority(AuthorityConstant.NORMAL_USER);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.addUser(user);
    }

    /**
     * 用户端用户登录
     *
     * @param userLoginDTO
     * @return
     */
    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        //获取用户名和密码
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();
        //通过用户名查找用户
        User user = userMapper.getUserByUsername(username);
        //没有该用户返回异常信息
        if(user==null){
            throw new AccountNotFoundException(MessageConstant.LOGIN_ERROR);
        }
        //校验密码
        if(!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())){
            throw new PasswordErrorException(MessageConstant.LOGIN_ERROR);
        }
        //校验该账号的状态
        if(Objects.equals(user.getAuthority(), AuthorityConstant.LOGOUT_USER)){
            throw new AccountLockedException(MessageConstant.ACCOUNT_ERROR);
        }

        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(),
                jwtProperties.getUserTtl(),
                claims);

        //返回VO对象
        return UserLoginVO.builder()
                 .id(user.getId())
                 .username(user.getUsername())
                 .avatarUrl(user.getAvatarUrl())
                 .token(token)
                 .build();
    }

    /**
     * 获取用户页面个人信息
     *
     * @param id
     * @return
     */
    @Override
    public UserInfoVO getUserInfo(Long id) {
        if(!Objects.equals(id, BaseContext.getCurrentId())) {
            throw new IdError(MessageConstant.ID_ABNORMAL);
        }
        User user = userMapper.getUserById(id);
        return UserInfoVO.builder()
                .username(user.getUsername())
                .nickname(user.getNickname())
                .name(user.getName())
                .phone(user.getPhone())
                .gender(user.getGender())
                .mail(user.getMail())
                .avatarUrl(user.getAvatarUrl())
                .build();
    }

    /**
     * 用户编辑页面信息回显
     *
     * @return
     */
    @Override
    public UserEditVO getEditInfo() {
        User user = userMapper.getUserById(BaseContext.getCurrentId());
        return UserEditVO.builder()
                .username(user.getUsername())
                .nickname(user.getNickname())
                .avatarUrl(user.getAvatarUrl())
                .name(user.getName())
                .gender(user.getGender())
                .phone(user.getPhone())
                .mail(user.getMail())
                .build();
    }

    /**
     * 用户编辑个人信息
     *
     * @param userEditInfoDTO
     */
    @Override
    public void editUser(UserEditInfoDTO userEditInfoDTO) {
        User user = new User();
        BeanUtils.copyProperties(userEditInfoDTO,user);
        user.setId(BaseContext.getCurrentId());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
    }
}
